//
//  Search+Search.m
//  ClinicalCollections
//
//  Created by janakiraman gopinath on 1/21/13.
//  Copyright (c) 2013 GOPI. All rights reserved.
//

#import "Search+Search.h"

#define MAX_CAPACITY 100
@implementation Search (Search)



+ (UIManagedDocument *) openDatabase
{
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
                  lastObject];
    url = [url URLByAppendingPathComponent:@CLINICAL_COLLECTIONS_DATABASE];
    
    return [[UIManagedDocument alloc] initWithFileURL:url];
}
+ (NSURL *) getUrlForDatabase
{
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
                  lastObject];
    url = [url URLByAppendingPathComponent:@CLINICAL_COLLECTIONS_DATABASE];
    return url;
}
+ (NSArray *)fetchSearchStringWithSearchType:(NSString *) searchType
                    inManagedDocumentContext:(NSManagedObjectContext *) context
{
    
    NSManagedObjectContext *moc = context;
    NSEntityDescription *entityDescription = [NSEntityDescription
                                              entityForName:@"Search" inManagedObjectContext:moc];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:
                              @"searchType = %@", searchType];
    
    [request setPredicate:predicate];
    NSSortDescriptor *dateDescSort = [[NSSortDescriptor alloc] initWithKey:@"last_accessed_date" ascending:NO];
    // Need to implement the selector
    request.sortDescriptors = [NSArray arrayWithObject:dateDescSort];
    
    NSError *error;
    NSArray *array = [moc executeFetchRequest:request error:&error];
    NSSet *distinctSearch = [[NSSet alloc] initWithArray:array];
    
    NSArray *returnArray = [distinctSearch allObjects];
    
    // Sort the data in decending order
    
    NSArray *sortedArray = [[[returnArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSDate *first = [a last_accessed_date];
        NSDate *second = [b last_accessed_date];
        return [first compare:second];
    }] reverseObjectEnumerator] allObjects];
    
    return sortedArray;
}

+ (Search *) updateSearch:(Search *) search
     withLastAccessedDate:(NSDate *) lastAccessedDate
             usingContext:(NSManagedObjectContext *) context
{
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Search"];
    request.predicate = [NSPredicate predicateWithFormat:@"searchType = %@ and searchString = %@ and recr = %@", search.searchType, search.searchString, search.recr];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"searchString" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    NSError *error = nil;
    
    
    NSArray *searchs = [context executeFetchRequest:request error:&error];
    
    Search *newSearch = [searchs lastObject];
    newSearch.last_accessed_date = lastAccessedDate;
    
    return newSearch;
    
}
+ (Search *)setSearchStringWithSearchType:(NSString *)searchType
                 inManagedDocumentContext:(NSManagedObjectContext *)context
                        usingSearchString:(NSString *) searchString
                                 recrType:(NSString *) recr
{
    Search *search = nil;
    
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Search"];
    request.predicate = [NSPredicate predicateWithFormat:@"searchType = %@ and searchString = %@ and recr = %@", searchType, searchString, recr];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"searchString" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    
    NSError *error = nil;
    
    NSArray *searchStrings = [context executeFetchRequest:request error:&error];
    
    if (!searchStrings || ([searchStrings count] > 1)) {
    } else if (![searchStrings count]) {
        search = [[self class] loadData:searchString
                           usingContext:context
                        usingSearchType:searchType
                               recrType:recr];
    } else {
        search = [searchStrings lastObject];
        
    }
    return search;
}

+ (NSDictionary *) clinicalCollectionsJSON_OR_EXHIBIT:(NSString *) searchString
                                           returnType:(enum API_LEVEL)level
                                             recrType:(NSString *) recr
{
    NSArray *keys, *values, *fields;
    keys = [[NSArray alloc] initWithObjects:@"term", @"recr" , nil];
    values = [[NSArray alloc] initWithObjects:searchString, recr, nil];
    
    if (level == JSON)
        fields = [[NSArray alloc] initWithObjects:@"id" , @"id_info", @"location", @"arm_group" , @"intervention" , @"primary_outcome" ,@"number_of_groups" , @"number_of_groups" , @"study_design", @"phase",
                  @"study_type" , @"secondary_outcome" ,  @"brief_title", @"overall_status", @"condition",
                  @"start_date" , @"end_date" , @"detailed_description", @"firstreceived_results_date",
                  @"firstreceived_date" , @"eligibility",
                  @"clinical_results", nil];
    else if (level == EXHIBIT)
        fields = [[NSArray alloc] initWithObjects:@"id" , @"location_latlong", @"cities", nil];
    
    
    NSDictionary *parameters = [[NSDictionary alloc] initWithObjects:values  forKeys:keys];
    
    if (level == JSON)
        // Load up the model
        return [ClinicalCollections clinicalCollectionsQueryfetchWithLimit:100 usingParameters:parameters selectingFields:fields];
    else if (level == EXHIBIT)
        return [ClinicalCollections clinicalCollectionsQueryExhibitfetchWithLimit:100 usingParameters:parameters selectingFields:fields];
    else
        return nil;
}

+ (Search *) loadData:(NSString *)searchString
         usingContext:(NSManagedObjectContext *) context
      usingSearchType:(NSString *)searchType
             recrType:(NSString *) recr
{
    
    Search *search = [NSEntityDescription insertNewObjectForEntityForName:@"Search"
                                                   inManagedObjectContext:context];
    search.searchType = searchType;
    search.searchString = searchString;
    search.recr = recr;
    search.last_accessed_date =  [NSDate dateWithTimeIntervalSinceNow:0];
    search.last_refresh_date =  [NSDate dateWithTimeIntervalSinceNow:0];
    
    NSDictionary *clinicalCollections ;//, *clinicalCollectionsExhibit;
    
    // Load up the model from Lilly COI
    
    clinicalCollections = [[self class] clinicalCollectionsJSON_OR_EXHIBIT:searchString
                                                                returnType:JSON
                                                                  recrType:recr];
    // clinicalCollectionsExhibit = [[self class] clinicalCollectionsJSON_OR_EXHIBIT:searchString
    //                                                                  returnType:EXHIBIT
    //                                                                 recrType:recr ];
    
    NSArray *results = [clinicalCollections valueForKey:@"results"];
    
    NSMutableSet *clinicalTrialGovSet = [[NSMutableSet alloc] initWithCapacity:MAX_CAPACITY];
    
    // Status variables
    NSMutableArray        *statusSet = [[NSMutableArray alloc] initWithCapacity:MAX_CAPACITY];
    NSMutableArray      *statusArray = [[NSMutableArray alloc] initWithCapacity:MAX_CAPACITY];
    NSMutableDictionary *statusDictionary = [[NSMutableDictionary alloc] initWithCapacity:MAX_CAPACITY];
    statusSet[0] = statusArray;
    statusSet[1] = statusDictionary;
    
    
    for (int i = 0; i < results.count; i++) {
        
        ClinicalTrialGov *clinicalTrialGov = [[ClinicalTrialGov class] clinicalTrialGov:search
                                                                       resultDictionary:results[i]
                                                                            withContext:context];
        
        // Load up and latitude, longitude and city from the exhibit collections
        NSArray *items = [results[i] valueForKey:@"location"];
        NSDictionary *latLongDict = [[Location class] locationLatLong:items forNCTID:clinicalTrialGov.nctID];
        if (latLongDict != nil) {
            
            if (![[latLongDict objectForKey:@"city"] isEqual:[NSNull null]])
                clinicalTrialGov.city = [latLongDict objectForKey:@"city"];
            
            if (![[latLongDict objectForKey:@"lat"] isEqual:[NSNull null]])
                clinicalTrialGov.lat = [latLongDict objectForKey:@"lat"];
            
            if (![[latLongDict objectForKey:@"lng"] isEqual:[NSNull null]])
                clinicalTrialGov.lng = [latLongDict objectForKey:@"lng"];
        }
        
        // Load up the distinct status table, check before if exists
        Status *status;
        if ([[CommonAPI class] getObjectFromSet:statusSet forObject:clinicalTrialGov.status forIndex:0])
            status = [[CommonAPI class] getObjectFromSet:statusSet forObject:clinicalTrialGov.status forIndex:1];
        else {
            status = [[Status class] status:clinicalTrialGov.status usingContext:context];
            status.search = search;
            [statusSet[0] addObject:clinicalTrialGov.status];
            [statusSet[1] setObject:status forKey:clinicalTrialGov.status];
        }
        
        clinicalTrialGov.distinctStatus = status;
        
        // Load up the conditions records
        NSArray *conditions = [results[i] valueForKey:@"condition"];
        [[Condition class] conditions:conditions
                           forContext:context
                  forClinicalTrialGov:clinicalTrialGov];
        // Load up eligibility
        [[Eligibility class] eligibility:[results[i] valueForKey:@"eligibility"]
                              forContext:context
                     forClinicalTrialGov:clinicalTrialGov];
        
        
        // Load up the location records
        
        NSArray *locations = [results[i] valueForKey:@"location"];
        [[Location class] locations:locations
                         forContext:context
                forClinicalTrialGov:clinicalTrialGov];
        
        // Load up ArmGroups
        [[ArmGroups class] armGroups:[results[i] valueForKey:@"arm_group"]
                          forContext:context
                 forClinicalTrialGov:clinicalTrialGov];
        
        // Load up outcomes
        // Primary outcome
        [[Outcome class] outcome:[results[i] valueForKey:@"primary_outcome"]
                            type:@"primary" forContext:context forClinicalTrialGov:clinicalTrialGov];
        // Secondary outcome
        [[Outcome class] outcome:[results[i] valueForKey:@"secondary_outcome"]
                            type:@"secondary" forContext:context forClinicalTrialGov:clinicalTrialGov];
        
        //Load up Interventions
        [[Intervention class] intervention:[results[i] valueForKey:@"intervention"]
                                forContext:context
                       forClinicalTrialGov:clinicalTrialGov];
        
        [[GroupTypes class] groupTypes:@"baseline"
                          usingResults:results[i]
                 usingClinicalTrialGov:clinicalTrialGov
                          usingContext:context];
        [[GroupTypes class] groupTypes:@"participant_flow"
                          usingResults:results[i]
                 usingClinicalTrialGov:clinicalTrialGov
                          usingContext:context];
        
        [[GroupTypes class] groupTypes:@"outcome_list"
                          usingResults:results[i]
                 usingClinicalTrialGov:clinicalTrialGov
                          usingContext:context];
        
        [clinicalTrialGovSet addObject:clinicalTrialGov];
    }
    search.clinicalTrialGov = clinicalTrialGovSet;
    
    return search;
}

+ (Search *)deleteSearchStringWithSearchType:(NSString *)searchType
                    inManagedDocumentContext:(NSManagedObjectContext *)context
                           usingSearchString:(NSString *) searchString
{
    Search *search = nil;
    
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Search"];
    request.predicate = [NSPredicate predicateWithFormat:@"searchType = %@ and searchString = %@", searchType, searchString];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"searchString" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    
    NSError *error = nil;
    NSArray *searchStrings = [context executeFetchRequest:request error:&error];
    
    if (!searchStrings || ([searchStrings count] > 1)) {
        
    } else if (![searchStrings count]) {
        
    } else {
        [context deleteObject:[searchStrings lastObject]];
    }
    return search;
}

@end
